﻿from django.db import models
from django.forms import ModelForm
from django import forms
from django.contrib.auth.models import User
from paypal.standard.ipn.signals import payment_was_successful
import random
import string
import logging
import datetime
from datetime import date
import settings
from django.core.mail import send_mail
from django.contrib.admin.widgets import AdminFileWidget
from django.db.models import permalink

# Create your models here.

class Article(models.Model): #文章

    id = models.AutoField(primary_key=True)
    user = models.ForeignKey(User)
    title = models.CharField(max_length=300, blank=True) #文章标题
    link = models.CharField(max_length=200, blank=True) #链接
    content = models.TextField(blank=True) #文章内容
    category = models.CharField(max_length=30, blank=False) #文章分类
    sub = models.CharField(max_length=50, blank=True)#子类
    video = models.TextField(blank=True) #视频地址，视频功能延后实现
    imgs = models.TextField(blank=True) #图片，以逗号分隔的多个图片地址，先保存图片并把地址存入此字段
    down = models.IntegerField(default=0)
    up = models.IntegerField(default=0)
    integral = models.FloatField() #积分
    date = models.DateTimeField()
    comment_count = models.IntegerField(default=0)
    year = models.IntegerField()
    week = models.IntegerField()

    def __unicode__(self):
        return self.title

    class Meta:
        db_table = u'article'


class ArticleForm(forms.Form):
    title = forms.CharField(max_length=50, error_messages={'required': u'标题不能为空'})
    content = forms.CharField(widget=forms.Textarea(attrs={'row:': '20', 'cols': '50'}),
                              error_messages={'required': u'文章内容不能空'})
    link = forms.CharField(required=False)
    video = forms.CharField(required=False)
    category = forms.CharField(error_messages={'required': u'文章分类不能为空'},
                               widget=forms.TextInput(attrs={'readonly': 'readonly'}))
    imgs = forms.CharField(required=False)


class Comment(models.Model): #评论
    id = models.AutoField(primary_key=True)
    article = models.ForeignKey(Article)
    content = models.TextField() #评论内容
    date = models.DateTimeField() #评论日期
    user = models.ForeignKey(User)

    class Meta:
        db_table = u'comment'


class Category(models.Model): #分类

    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=50)
    price = models.IntegerField(null=False) #价格
    pre_price = models.IntegerField(null=False)

    def __unicode__(self):
        return self.name

    class Meta:
        db_table = u'category'


class CategoryIntegral(models.Model): #分类积分

    id = models.AutoField(primary_key=True)
    category = models.CharField(max_length=20)
    user = models.ForeignKey(User)
    year = models.CharField(max_length=10) #年
    week = models.CharField(max_length=10) #周
    integral = models.IntegerField() #积分

    class Meta:
        db_table = u'category_integral'




class Ad(models.Model): #广告
    check_CHOICES = (
        (u'passed', u'passed'),
        (u'not pass', u'not pass'),
        )
    id = models.AutoField(primary_key=True)
    pay_to_paypal = models.CharField(max_length=100)
    pay_user = models.IntegerField(null=True)
    check = models.CharField(max_length=32, blank=True)
    reason = models.CharField(max_length=100, blank=True)
    category = models.ForeignKey(Category)  #分类即位置，按分类时间不可有冲突
    start_date = models.DateField(null=True)
    end_date = models.DateField(null=True)
    pre_date = models.DateTimeField(null=True) #添加日期
    date = models.DateTimeField(null=True, blank=True)
    init_date = models.DateTimeField(null=True)
    pay_flag = models.CharField(max_length=32, null=True, blank=True)
    pay_pre_flag = models.CharField(max_length=32, null=True, blank=True)
    content = models.CharField(max_length=512, null=True, blank=True)
    invoice = models.CharField(max_length=50, null=True, blank=True)
    pre_invoice = models.CharField(max_length=50, null=True, blank=True)
    ad_price = models.IntegerField(null=True) #广告总价
    pre_price = models.IntegerField(null=True) #预定价格

    def save(self, force_insert=False, force_update=False):
        if self.check:
            user = User.objects.get(pk=self.pay_user)
            try:
                send_mail('sns广告审核结果',
                    '请检查你的广告，广告状态为％s!' % self.check,
                    settings.EMAIL_HOST_USER, [user.email], fail_silently=False)
            except:
                pass
            dm = DirectMessage()
            from_user = User.objects.get(pk=1)#管理员
            dm.from_user = from_user
            dm.to_user = user
            dm.content = u'sns广告审核结果,请检查你的广告，广告状态为％s!' % self.check
            dm.save()
        super(Ad,self).save(force_insert,force_update)


    class Meta:
        db_table = u'ad'


class Gift(models.Model):
    id = models.AutoField(primary_key=True)
    pay_to_paypal = models.CharField(max_length=100)
    author_name = models.CharField(max_length=100, blank=True)
    date = models.DateTimeField(auto_now_add=True)
    article_id = models.CharField(max_length=50)
    price = models.CharField(max_length=50, blank=True)
    pay_flag = models.CharField(max_length=10, default='wait')
    pay_invoice = models.CharField(max_length=100)

    class Meta:
        db_table = u'gift'


class Board(models.Model):#圈子
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=50, blank=True)
    category = models.ForeignKey(Category)
    property = models.CharField(max_length=10)
    apply_date = models.DateTimeField(auto_now_add=True)
    about = models.CharField(max_length=300, blank=True)
    is_active = models.BooleanField(default=False)
    count = models.IntegerField(default=0)
    manager = models.ForeignKey(User)

    def __unicode__(self):
        return self.name

    class Meta:
        db_table = u'board'


class BoardForm(forms.Form):
    name = forms.CharField(max_length=50, error_messages={'required': u'圈子名字不能为空'})
    category = forms.ModelChoiceField(Category.objects, widget=forms.Select)
    property = forms.ChoiceField(widget=forms.Select(),
                                 choices=([('share', 'share'), ('help', 'help'), ]), required=True, )
    about = forms.CharField(widget=forms.Textarea(attrs={'row:': '20', 'cols': '50'}),
                            error_messages={'required': u'关于内容不能空'})


class BoardFollower(models.Model):
    id = models.AutoField(primary_key=True)
    board = models.ForeignKey(Board)
    user = models.ForeignKey(User)
    apply_date = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = u'board_follower'


class Friends(models.Model): #朋友

    id = models.IntegerField(primary_key=True)
    user = models.ForeignKey(User, related_name='user')
    follower = models.ForeignKey(User, related_name='follower') #关注者
    date = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = u'friends'


class UserProfile(models.Model): #用户扩展表，默认用django后果管理表作为用户表

    id = models.AutoField(primary_key=True)
    user = models.OneToOneField(User)
    paypal = models.CharField(max_length=50, blank=True) #paypal帐号
    role = models.CharField(max_length=10, blank=True, default=0) #用户角色，高级会员，普通会员
    pay_invoice = models.CharField(max_length=50, blank=True)
    start_date = models.DateField(blank=True, null=True) #高级会员开始时间
    end_dete = models.DateField(blank=True, null=True) #高级会员结束时间
    medal = models.CharField(max_length=50, blank=True) #奖章
    avatar = models.ImageField(upload_to='photos/%Y/%m/%d')#图像
    activation_key = models.CharField(max_length=50, blank=True)#激活码,密码找回时使用
    country = models.CharField(max_length=50, blank=True)
    state = models.CharField(max_length=50, blank=True)
    intro = models.CharField(max_length=200, blank=True)#个人简介
    followers = models.IntegerField(default=0) #被关注数
    follow = models.IntegerField(default=0) #关注数
    limit_article_date = models.DateTimeField(blank=True, null=True)
    limit_dm_date = models.DateTimeField(blank=True, null=True)


    class Meta:
        db_table = u'user_profile'


class UserPaySenior(models.Model):
    id = models.AutoField(primary_key=True)
    user = models.ForeignKey(User)
    pay_flag = models.CharField(max_length=10, default='fail')
    pay_date = models.DateTimeField(auto_now_add=True)
    price = models.IntegerField()
    months = models.IntegerField()
    pay_invoice = models.CharField(max_length=100)

    class Meta:
        db_table = u'user_pay_senior'


class DirectMessage(models.Model): #私信

    id = models.AutoField(primary_key=True)
    from_user = models.ForeignKey(User, related_name='from_user')
    to_user = models.ForeignKey(User, related_name='to_user')
    content = models.CharField(max_length=200, blank=True)
    is_read = models.IntegerField(default=0)
    date = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = u'direct_message'


class Report(models.Model): #举报

    id = models.AutoField(primary_key=True)
    article_id = models.IntegerField()
    dm_id = models.IntegerField()
    user = models.ForeignKey(User)
    reason = models.CharField(max_length=200)
    date = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = u'report'


class Vote_history(models.Model):
    id = models.AutoField(primary_key=True)
    article_id = models.IntegerField()
    user_id = models.IntegerField()
    ticket = models.CharField(max_length=32)

    class Meta:
        db_table = u'vote_history'


class PaypalFilter(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=200)

    class Meta:
        db_table = u'paypal_filter'


class Contact(models.Model):
    id = models.AutoField(primary_key=True)
    email = models.EmailField(max_length=100, blank=True)
    name = models.CharField(max_length=100, blank=True)
    title = models.CharField(max_length=50, blank=True)
    file = models.FileField(upload_to='files/%Y/%m/%d', blank=True, null=True)
    content = models.CharField(max_length=500, blank=True)
    date = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = u'contact'


class ContactForm(ModelForm):
    content = forms.CharField(widget=forms.Textarea)

    class Meta:
        model = Contact
        exclude = ('id', 'date')


class UserProfileForm(ModelForm):
    class Meta:
        model = UserProfile
        fields = ('paypal', 'avatar')


class UserForm(ModelForm):
    password = forms.CharField(max_length=30, widget=forms.PasswordInput(attrs={'size': 20, }))

    class Meta:
        model = User
        fields = ('username', 'email', 'password')


class LoginForm(ModelForm):
    username = forms.CharField(max_length=30, widget=forms.TextInput(attrs={'size': 20, }))
    password = forms.CharField(max_length=30, widget=forms.PasswordInput(attrs={'size': 20, }))

    class Meta:
        model = User
        fields = ('username', 'password')


class ResetPassForm(forms.Form):
    email = forms.EmailField(max_length='200')

    class Meta:
        pass


def show_me_the_money(sender, **kwargs):
    ipn_obj = sender
    if ipn_obj.payment_status == 'Completed':
        if ipn_obj.item_number == 'senior' and ipn_obj.payer_status == 'verified':
            userPaySenior = UserPaySenior.objects.get(pay_invoice=ipn_obj.invoice)
            list = PaypalFilter.objects.filter(name=ipn_obj.payer_bussiness_name)
            if list:
                userPaySenior.pay_flag = 'suspend'
            else:
                userPaySenior.pay_flag = 'success'
            userPaySenior.save()
            userProfile = userPaySenior.user.userprofile
            current_date = date.today()
            if userProfile.end_dete:
                if userProfile.end_dete > current_date:
                    userProfile.end_dete = datetime_offset_by_month(userProfile.end_dete, userPaySenior.months)
                    userProfile.save()
            else:
                userProfile.start_date = current_date
                userProfile.end_dete = datetime_offset_by_month(current_date, userPaySenior.months)
                userProfile.save()
        if ipn_obj.item_number == 'ad_pre':
            ad = Ad.objects.get(pre_invoice=ipn_obj.invoice)
            ad.pay_pre_flag = 'success'
            ad.save()
            try:
                send_mail('预购广告成功',
                          '预购广告成功,预购号为%s,请审核广告内容!' % ipn_obj.invoice,
                          settings.EMAIL_HOST_USER, [settings.ADMIN_EMAIL], fail_silently=False)
            except:
                pass

        if ipn_obj.item_number == 'ad':
            ad = Ad.objects.get(invoice=ipn_obj.invoice)
            ad.pay_flag = 'success'
            ad.save()
            try:
                send_mail('广告支付成功',
                          '广告支付成功,付款号为%s' % ipn_obj.invoice,
                          settings.EMAIL_HOST_USER, [settings.ADMIN_EMAIL], fail_silently=False)
            except:
                pass
        if ipn_obj.item_number == 'gift':
            gift = Gift.objects.get(pay_invoice=ipn_obj.invoice)
            gift.pay_flag = 'success'
            gift.save()


payment_was_successful.connect(show_me_the_money)


def datetime_offset_by_month(datetime1, n=1):
    # create a shortcut object for one day
    one_day = datetime.timedelta(days=1)

    # first use div and mod to determine year cycle
    q, r = divmod(datetime1.month + n, 12)

    # create a datetime2
    # to be the last day of the target month
    datetime2 = datetime.datetime(
        datetime1.year + q, r + 1, 1) - one_day

    # if input date is the last day of this month
    # then the output date should also be the last
    # day of the target month, although the day
    # may be different.
    # for example:
    # datetime1 = 8.31
    # datetime2 = 9.30
    if datetime1.month != (datetime1 + one_day).month:
        return datetime2

    # if datetime1 day is bigger than last day of
    # target month, then, use datetime2
    # for example:
    # datetime1 = 10.31
    # datetime2 = 11.30
    if datetime1.day >= datetime2.day:
        return datetime2

    # then, here, we just replace datetime2's day
    # with the same of datetime1, that's ok.
    return datetime2.replace(day=datetime1.day)




